#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <unordered_set>
#include <chrono>
#include <climits>  

using namespace std;

long long C;
long long N;
vector<long long> w; //重量数组
vector<long long> p; //价值数组
vector<pair<double,int>> items;//first为价值密度,second为编号
vector<int> ans; //最优方案
long long max_value = INT_MIN; //当前最优值


//分支限界法节点定义
struct Node {
    long long level;    //当前层级
    long long weight;   //当前总重量
    long long value;    //当前总价值
    double bound;    //上界
    vector<int> selected;
    bool operator<(const Node& other) const {
        return bound < other.bound;  //最大堆
    }
};

void preProcess(){ //预处理
    max_value = 0; 
    for(int i = 0;i < w.size();i++)
        items.push_back({(p[i] * 1.0) / (w[i] * 1.0),i});
    sort(items.begin(),items.end(),greater<pair<double,int>>()); //降序
}

//按部分背包问题计算剩余物品最大价值
double calculateBound(Node& node){ 
    if(node.weight >= C) return node.value;

    double bound = node.value;
    long long remaining = C - node.weight;
    int i = node.level + 1;
    //尽量装入完整物品
    while(i < N && w[items[i].second] <= remaining){
        bound += p[items[i].second];
        remaining -= w[items[i].second];
        i++;
    }
    //装入部分物品
   if (i < N) bound += remaining * items[i].first;
    return bound;
}

long long bb_knapsack01() {
    preProcess();

    priority_queue<Node> pq; //最大堆
    Node ini = {-1,0,0,0.0};
    ini.bound = calculateBound(ini);
    pq.push(ini); //初始节点
    
    while(!pq.empty()){
        Node node = pq.top(); 
        pq.pop();

        if(node.value > max_value){ //更优
            max_value = node.value; //更新当前最大价值
            ans = node.selected;
        } 

        //拓展节点
        int next = node.level + 1;
        if (next >= N) continue;
        int idx = items[next].second;

        //选下一个物品（左孩子）
        if(node.weight + w[idx] <= C){
            Node chosen = node;
            chosen.level = next;
            chosen.weight += w[idx];
            chosen.value += p[idx];
            chosen.selected.push_back(idx);
            chosen.bound = calculateBound(chosen);
            if(chosen.bound > max_value) pq.push(chosen);
        }

        //不选下一个物品（右孩子）
        Node not_chosen = node;
        not_chosen.level = next;
        not_chosen.bound = calculateBound(not_chosen);
        if(not_chosen.bound > max_value) pq.push(not_chosen);
    }
    
    return max_value;
}


void print_result(){
    //执行,计时
    auto start = chrono::high_resolution_clock::now(); //开始计时
    bb_knapsack01();
    printf("%lld\n",max_value);
    sort(ans.begin(),ans.end());
    for(int i = 0;i < ans.size();i++) printf("%d ",ans[i] + 1);
    printf("\n");
    auto end = std::chrono::high_resolution_clock::now(); //结束计时
    //计算持续时间
    auto duration = chrono::duration_cast<chrono::microseconds>(end - start);
    printf("%fms\n",duration.count() / 1000.0);
}


int main(){
    scanf("%lld %lld",&N,&C);
    w.resize(N);
    p.resize(N);
    for(int i = 0;i < N;i++) scanf("%lld %lld",&p[i],&w[i]);
    print_result();
    return 0;
}